package com.yc.pos;

import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Created by Administrator on 2015-11-20.
 */
public class DigitalUtil {

    /**
     * 将16位的short转换成byte数组
     *
     * @param s
     *            short
     * @return byte[] 长度为2
     * */
    public static byte[] shortToByteArray(short s) {
        byte[] targets = new byte[2];
        for (int i = 0; i < 2; i++) {
            int offset = (targets.length - 1 - i) * 8;
            targets[i] = (byte) ((s >>> offset) & 0xff);
        }
        return targets;
    }

    // 整数到字节数组转换
    public static byte[] int2bytesBy32(int n) {
        byte[] ab = new byte[4];
        ab[0] = (byte) (0xff & n);
        ab[1] = (byte) ((0xff00 & n) >> 8);
        ab[2] = (byte) ((0xff0000 & n) >> 16);
        ab[3] = (byte) ((0xff000000 & n) >> 24);
        return ab;
    }

    // 整数到字节数组转换
    public static byte[] int2bytesBy16(int n) {
        byte[] ab = new byte[2];
        // ab[0] = (byte) (0xff & n);
        // ab[1] = (byte) ((0xff00 & n) >> 8);

        ab[0] = (byte) ((0xff00 & n) >> 8);
        ab[1] = (byte) (0xff & n);

        return ab;
    }

    // 字节数组到整数的转换
    public static int bytes2int(byte b[]) {
        int s = 0;
        s = ((((b[0] & 0xff) << 8 | (b[1] & 0xff)) << 8) | (b[2] & 0xff)) << 8
                | (b[3] & 0xff);
        return s;
    }

    // 字节转换到字符
    public static char byte2char(byte b) {
        return (char) b;
    }

    private final static byte[] hex = "0123456789ABCDEF".getBytes();

    private static int parse(char c) {
        if (c >= 'a')
            return (c - 'a' + 10) & 0x0f;
        if (c >= 'A')
            return (c - 'A' + 10) & 0x0f;
        return (c - '0') & 0x0f;
    }

    // 从字节数组到十六进制字符串转换
    public static String Bytes2HexString(byte[] b) {
        byte[] buff = new byte[2 * b.length];
        for (int i = 0; i < b.length; i++) {
            buff[2 * i] = hex[(b[i] >> 4) & 0x0f];
            buff[2 * i + 1] = hex[b[i] & 0x0f];
        }
        return new String(buff);
    }

    // 从字节数组到十六进制字符串转换 用这个
    public static String MyBytes2HexString(byte[] b) {
        String ret = "";
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase(Locale.getDefault());
            // ret += hex;
        }
        return ret;
    }
    // 从十六进制字符串到字节数组转换
    public static byte[] HexString2Bytes(String hexstr, int len) {
        if(hexstr.length()==0)
            return new byte[1];

        byte[] b = new byte[len];
        int j = 0;
        for (int i = 0; i < b.length; i++) {
            if (j < hexstr.length()) {
                char c0 = hexstr.charAt(j++);
                char c1 = hexstr.charAt(j++);
                b[i] = (byte) ((parse(c0) << 4) | parse(c1));
            }
        }

        return b;
    }
    // 从十六进制字符串到字节数组转换
    public static byte[] HexString2Bytes(String hexstr) {
        if(hexstr.length()==0)
            return new byte[1];
        byte[] b = new byte[hexstr.length() / 2];
        int j = 0;
        for (int i = 0; i < b.length; i++) {
            char c0 = hexstr.charAt(j++);
            char c1 = hexstr.charAt(j++);
            b[i] = (byte) ((parse(c0) << 4) | parse(c1));
        }
        return b;
    }

    // 从十进制字符串到字节数组转换
    public static byte[] DexString2Bytes(String decstr) {
        String stTemp;
        byte[] b = new byte[decstr.length() / 2];
        int j = 0;

        for (int i = 0; i < decstr.length(); i += 2) {
            stTemp = decstr.substring(i, i + 2);
            b[j++] = (byte) Integer.parseInt(stTemp);
        }
        return b;
    }

    public static String hexString2DexString(String hex){
        BigInteger bigInteger = new BigInteger(StrReverseByte(hex),16);
        String dex = String.valueOf(bigInteger);
        return dex;
    }

    /**
     * 字符串反转,前提每两个字符转如:2669CCDD==>DDCC6926,1234-->3412
     *
     * @param orig
     * @return
     */
    public static String StrReverseByte(String orig) {
        String strr = "";
        int iLen = orig.length();
        for (int i = 0; i < iLen; i += 2) {
            strr = orig.substring(i, i + 2) + strr;
        }
        return strr;
    }

    /***
     * 将16进制字符串进行高低位变换后转成数字字符串,如:"01000000"-->"1","A000000"-->"10"
     *
     * @param orig
     * @return 如:2669CC7F(2144102694) 2669CC80(2160879910) 注意负数也会变成相应的正数
     */
    public static String StrConDigitFromS(String orig) {
        // 卡流水号:01000000 2669CC7F(2144102694) 2669CC80(2160879910)
        String strt = orig;// "2669CC80";//01000000(1) A000000(10) A0000000(160)
        // 2669CCDD(3721160998)
        String strr = "";
        strr = StrReverseByte(strt);
        byte bb[] = HexString2Bytes(strr);
        long iValue = bytetoshort(bb);
        iValue = getUnsignedLong(iValue);
        if (iValue < 0) {
            iValue = 0 - iValue;
            iValue = 4294967295L - iValue;
            iValue = iValue + 1;
        }
        String s = String.valueOf(iValue);
        return s;
    }

    /***
     * 将16进制字符串进行高低位变换后转成数字,如:"01000000"-->1,"A000000"-->10
     *
     * @param orig
     * @return 如:2669CC7F(2144102694) 2669CC80(2160879910) 注意负数也会变成相应的正数
     */
    public static int StrConDigitFromI(String orig) {
        // 卡流水号:01000000 2669CC7F(2144102694) 2669CC80(2160879910)
        String strt = orig;// "2669CC80";//01000000(1) A000000(10) A0000000(160)
        // 2669CCDD(3721160998)
        String strr = "";
        strr = StrReverseByte(strt);
        byte bb[] = HexString2Bytes(strr);
        long iValue = bytetoshort(bb);
        iValue = getUnsignedLong(iValue);
        if (iValue < 0) {
            iValue = 0 - iValue;
            iValue = 4294967295L - iValue;
            iValue = iValue + 1;
        }

        return (int) iValue;
    }


    /***
     * 将十进制字符串,如:"20150823133400"-->"20150822113400"
     *将时间减掉16小时,这里不解，为什么平板是这样的???
     * 如:20150823133400-16小时=20150822113400
     * @param orig
     * @return 方法首先转成秒,然后减掉后面的long秒值取一个新值再转成字符串
     */
    public static String StrConChangeBet(String orig, long ltime) {
        String time = "";
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd.HHmmss");
        Date date = null;
        try {
            date = df.parse(orig);
            long llt = date.getTime();
            llt = llt - (ltime * 3600 * 1000)+1000;
            date.setTime(llt);
            time = df.format(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return time;
    }


    /**
     * 从底层取年月日时分秒 分别存在字符串数组中，按顺序 字符0--年,字符1--月,字符2--日, 字符3--时,字符4--分,字符5--秒
     * @param stra
     */
    public static void GetDateA(String []stra){
        byte[] aa = new byte[64];

        String res = new String(aa);//,"UTF-8");//取得值:10/17/15 18:46:48 Sat
        String strTemp;


        strTemp = res.substring(0, 2);//月
        stra[1] = strTemp;
        strTemp = res.substring(3, 5);//日
        stra[2] = strTemp;
        strTemp = "20" + res.substring(6, 8);//年
        stra[0] = strTemp;
        strTemp = res.substring(9, 11);//时
        stra[3] = strTemp;
        strTemp = res.substring(12, 14);//分
        stra[4] = strTemp;
        strTemp = res.substring(15, 17);//秒
        stra[5] = strTemp;
        strTemp = res.substring(18, 21);//星期
        if (strTemp.equals("Sun")){
            stra[6] = "1";
        }
        else if (strTemp.equals("Mon")){
            stra[6] = "2";
        }
        else if (strTemp.equals("Tue")){
            stra[6] = "3";
        }
        else if (strTemp.equals("Wed")){
            stra[6] = "4";
        }
        else if (strTemp.equals("Thu")){
            stra[6] = "5";
        }
        else if (strTemp.equals("Fri")){
            stra[6] = "6";
        }
        else if (strTemp.equals("Sat")){
            stra[6] = "7";
        }
        return;
    }

    /***
     * 将16进制字符串转成十进制字符串,如:"0F0801140930"-->"150801200948","0f0514120d2a"-->
     * "150520181342"
     *
     * @param orig
     * @return 方法首先转成16进制数组,然后一个一个转成数字,最后合成数字字符串
     */
    public static String StrConDigitFromHex(String orig, boolean bFlag) {

        String strt = orig;// "0F0801140930"
        int i = 0;
        int value = 0;
        String strr = "";
        byte bb[] = HexString2Bytes(strt);
        for (i = 0; i < bb.length; i++) {
            if (i == 3) {
                if (bFlag) {
                    strr += ".";
                }
            }
            value = (int) bb[i];
            if (value < 0) {
                value = 0 - value;
                value = 255 - value;
                value = value + 1;
            }
            if (value >= 10) {
                strr += "" + value;
            } else {
                strr += "0" + value;
            }
        }

        return strr;
    }

    /***
     * 将两个十进制字符串转成数字,然后比较,返回前者比后者的大小,如oriS=5,oriC=3,那么返回2,返之为-2,如果两个相等则返回0
     *
     * @param
     * @return
     */
    public static long StrCompareDigitFromDec(String oriS, String oriC) {
        long iOriS = Long.valueOf(oriS, 10);
        long iOriC = Long.valueOf(oriC, 10);

        long lRet = iOriS - iOriC;
        if ( lRet < 0 ){
            return (0-lRet);
        }

        return lRet;
    }

    /**
     * 取得黑名单个数1及数据,将个数数值不是字符串存入bwList中
     *
     * @param sOri
     *            ,如:sOri:00002f
     *            000100000002000000030000000400000005000000060000000700000008000000090000000
     *            a0000000b0000000c0000000d0000000e0000000f0000001100000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f00000031000000320000003300000092d00300
     * @return
     */
    public static int GetBWList1Value(String sOri, int bwList[]) {
        String strTemp = "";
        int iTemp = 0;
        int ik = 0;
        int i = 0;
        int iSkip = 0;
        int iTotal = 0;
        if (sOri.equals("") || sOri.startsWith("7620")) {
            return 0;
        }

        strTemp = sOri.substring(0, 4);// 表示(0-挂失，1-解挂)
        strTemp += "0000";// 凑成8字符(4byte)
        iTemp = StrConDigitFromI(strTemp);// 将16进制字符串进行高低位变换后转成数字,如:"01000000"-->1,"A000000"-->10
        bwList[ik++] = iTemp;

        strTemp = sOri.substring(4, 8);// //表示(黑名单个数)
        strTemp += "0000";// 凑成8字符(4byte)
        iTemp = StrConDigitFromI(strTemp);
        bwList[ik++] = iTemp;
        iTotal = iTemp;

        for (i = 0; i < iTotal; i++) {
            strTemp = sOri.substring(8 + iSkip, 16 + iSkip);
            iTemp = StrConDigitFromI(strTemp);
            bwList[ik + i] = iTemp;
            iSkip += 8;
        }

        return 1;
    }

    /**
     * 取得黑名单个数2及数据,将个数数值不是字符串存入bwList中
     *
     * @param sOri
     *            :sOri:010002003000000034000000762004009c000000
     * @return
     */
    public static int GetBWList2Value(String sOri, int bwList[]) {
        int iRet = GetBWList1Value(sOri, bwList);

        return iRet;
    }

    public static int COM_CRC_POLYNOMIAL = 0x8408;
    public static int COM_CRC_PRESET_VALUE = 0xFFFF;


    public static int CalculateCRC16(byte[] data) {
        int i, j, m;
        int crc = COM_CRC_PRESET_VALUE;
        int number_of_bytes = data[0] - 2; // in a LEGIC command the first
        // byte of a array/string holds
        // the number of following bytes
        for (i = 0; i <= number_of_bytes; i++) // loop over all the bytes which
        {
            m = getUnsignedByte(data[i]); // are used to build the crc
            crc = crc ^ m; // xor the crc with the next byte
            for (j = 0; j < 8; j++) // loop over each bit
            {
                if ((crc & 0x0001) == 1) // if the last bit of the crc is 1
                {
                    crc = (crc >> 1) ^ COM_CRC_POLYNOMIAL;// then xor the crc
                    // with the
                } // polynom and shift the crc
                else // else shift the crc
                {
                    crc = (crc >> 1);
                }
            }
        }
        return crc;
    }

    public static String CalculateStringCRC16(String hexstr) {
        byte[] data = HexString2Bytes(hexstr);
        int intValue = CalculateCRC16(data);
        return Bytes2HexString(int2bytesBy16(intValue))
                .toLowerCase();
    }

    public static int getUnsignedByte(byte data) { // 将data字节型数据转换为0~255 (0xFF
        // 即BYTE)。
        return data & 0x0FF;
    }

    public static int getUnsignedShort(short data) { // 将data字节型数据转换为0~65535
        // (0xFFFF 即 WORD)。
        return data & 0x0FFFF;
    }

    public static long getUnsignedInt(int data) { // 将int数据转换为0~4294967295
        // (0xFFFFFFFF即DWORD)。
        return data & 0x0FFFFFFFF;
    }

    public static long getUnsignedLong(long data) { // 将int数据转换为0~4294967295
        // (0xFFFFFFFF即DWORD)。
        return data & 0xFFFFFFFF;
    }

    public static int bytetoshort(byte b[]) {

        int mask = 0xff;
        int temp = 0;
        int n = 0;
        for (int i = 0; i < 4; i++) {
            n <<= 8;
            temp = b[i] & mask;
            n |= temp;
        }
        return n;
    }

    public static int GetSocketCrc(byte[] data, int length) {
        int crc = 0;
        int i, j, m;

        for (j = 0; j < length; j++) {
            m = getUnsignedByte(data[j]);
            crc ^= m;
            for (i = 0; i < 8; i++) {
                if ((crc & 0x01) != 0) {
                    crc >>= 1;
                    crc ^= 0x8c;
                } else {
                    crc >>= 1;
                }
            }
        }

        return crc;
    }

    public static String Get16Len(int len)
    {
        return Integer.toHexString(len).toLowerCase();
    }

    public static Long Get10Value(String value)
    {
        return Long.parseLong(value, 16);
    }

    public static Integer hexString2DecInt(String value)
    {
        return Integer.parseInt(value, 16);
    }

    public static String GetTempValue(String value,int length)
    {
        int len=value.length();
        String strFlag="";
        if(len<length)
        {
            for(int i=0;i<length-len;i++)
            {
                strFlag=strFlag+"0";
            }
        }

        return strFlag+value;
    }

    public static String decInt2HexString(int value){
        return GetTempValue(Get16Len(value),4);
    }

}
